package org.bjf.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bjf.exception.ServiceException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Jackson 工具类
 */
@Slf4j
public class JsonUtil {
    private final static ObjectMapper mapper = new ObjectMapper();
    /**
     * 日起格式化
     */
    private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";

    static {
        //对象的所有字段全部列入
//        mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        //取消默认转换timestamps形式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, Boolean.FALSE);
        //忽略空Bean转json的错误
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, Boolean.FALSE);
        //所有的日期格式都统一为以下的样式，即yyyy-MM-dd HH:mm:ss
        mapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
        //忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE);
        //忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE);
        //使用Jackson转换带下划线的属性为驼峰属性
        mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
    }

    private JsonUtil() {
    }

    public static ObjectMapper getInstance() {
        return mapper;
    }

    /**
     * 转换为 JSON 字符串
     */
    public static String toJSONString(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return obj instanceof String ? (String) obj : mapper.writeValueAsString(obj);
        } catch (Exception e) {
            throw new ServiceException("json 转换出错", e);
        }
    }


    /**
     * 对象转Json格式字符串(格式化的Json字符串)
     */
    public static String toJSONStringPretty(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            return obj instanceof String ? (String) obj : mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (Exception e) {
            throw new ServiceException("json 转换出错", e);
        }
    }


    /**
     * 字符串转换为自定义对象
     */
    public static <T> T parseObject(String json, Class<T> clz) {
        if (StringUtils.isBlank(json) || clz == null) {
            return null;
        }
        try {
            return clz.equals(String.class) ? (T) json : mapper.readValue(json, clz);
        } catch (Exception e) {
            throw new ServiceException("json 转换出错", e);
        }
    }


    /**
     * 将 JSON 数组转换为集合
     */
    public static <T> List<T> parseArray(String jsonArr, Class<T> clz) {
        JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, clz);
        try {
            return mapper.readValue(jsonArr, javaType);
        } catch (Exception e) {
            throw new ServiceException("json 转换出错", e);
        }

    }

    /**
     * 将 Map 转换为 JavaBean
     */
    public static <T> T map2bean(Map map, Class<T> clazz) {
        return mapper.convertValue(map, clazz);
    }


    /**
     * 将 JSON 对象转换为 JavaBean
     */
    public static <T> T obj2bean(Object obj, Class<T> clazz) {
        return mapper.convertValue(obj, clazz);
    }
}